﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


using System;
using Tesla.Math;

namespace Tesla.Graphics.Implementation {

    /// <summary>
    /// Abstract class for concrete subclasses to provide the underlying implementation of <see cref="SwapChain"/>.
    /// </summary>
    public abstract class SwapChainImplementation : GraphicsResourceImplementation {

        /// <summary>
        /// Gets the presentation parameters the swap chain is set to.
        /// </summary>
        public abstract PresentationParameters PresentationParameters {
            get;
        }

        /// <summary>
        /// Gets if the swap chain is in full screen mode or not. By default, swap chains
        /// are not in full screen.
        /// </summary>
        public abstract bool IsFullScreen {
            get;
        }

        /// <summary>
        /// Gets if the current display mode is in wide screen or not.
        /// </summary>
        public abstract bool IsWideScreen {
            get;
        }

        /// <summary>
        /// Gets the current display mode of the swap chain.
        /// </summary>
        public abstract DisplayMode CurrentDisplayMode {
            get;
        }

        /// <summary>
        /// Gets the window handle the swap chain is bound to.
        /// </summary>
        public abstract IntPtr WindowHandle {
            get;
        }

        /// <summary>
        /// Gets the handle to the monitor that contains the majority of the output.
        /// </summary>
        public abstract IntPtr MonitorHandle {
            get;
        }

        /// <summary>
        /// Sets the swapchain's backbuffer as the active render target and clears it.
        /// </summary>
        /// <remarks>
        /// The use of a swapchain differs slightly from using render targets. When a swapchain's
        /// targets are set to the device, other render targets (off screen) can be set. To make
        /// the backbuffer active again, simply set null to the renderer.
        /// </remarks>
        /// <param name="options">Clear option flags defining which buffer to clear.</param>
        /// <param name="color">Color to clear the color buffer to</param>
        /// <param name="depth">Depth value to clear the depth buffer to</param>
        /// <param name="stencil">Stencil value to clear the stencil buffer to</param>
        public abstract void Clear(ClearOptions options, Color color, float depth, int stencil);

        /// <summary>
        /// Gets the backbuffer as an array of data.
        /// </summary>
        /// <typeparam name="T">Specified data type</typeparam>
        /// <param name="rect">Rectangle defining the sub-image, if null the whole image is returned</param>
        /// <param name="data">The array to store the data in</param>
        /// <param name="startIndex">The starting index in the array</param>
        /// <param name="elementCount">The number of elements to copy</param>
        public abstract void GetBackBufferData<T>(Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct;

        /// <summary>
        /// Presents the contents of the back buffer to the screen, and flips the front/back buffers.
        /// </summary>
        public abstract void Present();

        /// <summary>
        /// Resizes the backbuffer.
        /// </summary>
        /// <param name="width">Width of the back buffer</param>
        /// <param name="height">Height of the back buffer</param>
        public abstract void Resize(int width, int height);

        /// <summary>
        /// Resets the swapchain.
        /// </summary>
        /// <param name="windowHandle">The new window handle to bind to</param>
        /// <param name="presentParams">The new presentation parameters to use</param>
        public abstract void Reset(IntPtr windowHandle, PresentationParameters presentParams);

        /// <summary>
        /// Toggles the swap chain to full screen mode.
        /// </summary>
        public abstract void ToggleFullScreen();
    }
}
